package com.cqh.recruit.task;

/**
 * @Description:
 * @Author: DengHao
 * @Date: 2025/10/26 10:12
 */

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cqh.recruit.pojo.entity.Activity;
import com.cqh.recruit.service.IActivityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * 活动状态自动更新定时任务
 *
 * 状态说明：
 * 1 - 未开始：当前日期 < 报名开始时间
 * 2 - 报名中：报名开始时间 <= 当前日期 <= 报名结束时间
 * 3 - 进行中：活动开始时间 <= 当前日期 <= 活动结束时间
 * 4 - 已结束：当前日期 > 活动结束时间
 * 5 - 已取消：手动设置，定时任务不处理
 */
@Component
public class ActivityStatusUpdateTask {

    private static final Logger log = Logger.getLogger(ActivityStatusUpdateTask.class.getName());

    @Autowired
    private IActivityService activityService;

    /**
     * 定时更新活动状态（定时任务自动调用）
     * cron表达式：每天凌晨1点执行一次
     *
     * cron表达式说明：秒 分 时 日 月 周
     * 0 0 1 * * ? 表示每天凌晨1点执行
     */
    @Scheduled(cron = "0 0 1 * * ?")// 每天凌晨1点执行
    public void autoUpdateActivityStatus() {
        log.info("========== 定时任务：开始执行活动状态自动更新 ==========");
        updateActivityStatus();
        log.info("========== 定时任务：活动状态自动更新完成 ==========");
    }

    /**
     * 手动更新活动状态（提供给Controller调用）
     * @return 更新的活动数量
     */
    public int updateActivityStatus() {
        log.info("========== 开始执行活动状态更新任务 ==========");

        try {
            // 1. 查询所有未结束且未取消的活动
            //    只查询状态为 1,2,3 的活动（未开始、报名中、进行中）
            LambdaQueryWrapper<Activity> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(Activity::getStatus, 1, 2, 3)
                    .eq(Activity::getDeleted, 0); // 未删除的活动

            List<Activity> activities = activityService.list(wrapper);

            if (activities == null || activities.isEmpty()) {
                log.info("没有需要更新状态的活动");
                log.info("========== 活动状态更新任务完成 ==========");
                return 0;
            }

            log.info("找到 " + activities.size() + " 个需要检查状态的活动");

            // 2. 获取当前日期
            LocalDate now = LocalDate.now();
            int updateCount = 0;

            // 3. 遍历活动，根据时间判断并更新状态
            for (Activity activity : activities) {
                Integer oldStatus = activity.getStatus();
                Integer newStatus = calculateActivityStatus(activity, now);

                // 如果状态有变化，更新数据库
                if (!oldStatus.equals(newStatus)) {
                    activity.setStatus(newStatus);
                    boolean success = activityService.updateById(activity);

                    if (success) {
                        updateCount++;
                        log.info("活动[ID:" + activity.getId() + ", 名称:" + activity.getName() +
                                "] 状态更新: " + getStatusName(oldStatus) + " -> " + getStatusName(newStatus));
                    } else {
                        log.severe("活动[ID:" + activity.getId() + ", 名称:" + activity.getName() + "] 状态更新失败");
                    }
                }
            }

            log.info("活动状态更新完成，共更新 " + updateCount + " 个活动状态");
            log.info("========== 活动状态更新任务完成 ==========");
            return updateCount;

        } catch (Exception e) {
            log.log(Level.SEVERE, "========== 活动状态更新任务执行失败 ==========", e);
            throw new RuntimeException("活动状态更新失败：" + e.getMessage(), e);
        }
    }

    /**
     * 计算活动应该处于的状态
     * @param activity 活动信息
     * @param now 当前日期
     * @return 新状态
     */
    private Integer calculateActivityStatus(Activity activity, LocalDate now) {
        // 优先级1：判断活动是否已结束
        if (now.isAfter(activity.getActivityEndTime())) {
            return 4; // 已结束
        }

        // 优先级2：判断活动是否进行中
        if (!now.isBefore(activity.getActivityStartTime()) &&
                !now.isAfter(activity.getActivityEndTime())) {
            return 3; // 进行中
        }

        // 优先级3：判断是否在报名时间内
        if (!now.isBefore(activity.getSignupStartTime()) &&
                !now.isAfter(activity.getSignupEndTime())) {
            return 2; // 报名中
        }

        // 优先级4：报名还未开始
        if (now.isBefore(activity.getSignupStartTime())) {
            return 1; // 未开始
        }

        // 特殊情况：报名已结束，但活动未开始
        // 保持为未开始状态，等待活动开始
        return 1;
    }

    /**
     * 获取状态名称（用于日志输出）
     */
    private String getStatusName(Integer status) {
        if (status == null) {
            return "未知";
        }
        switch (status) {
            case 1:
                return "未开始";
            case 2:
                return "报名中";
            case 3:
                return "进行中";
            case 4:
                return "已结束";
            case 5:
                return "已取消";
            default:
                return "未知(" + status + ")";
        }
    }
}
